﻿using System;
using System.Web;
using User.EF.Contracts;
using User.EF.Model;
using User.EF.Queries;

namespace User.Web.UI.Helper.RightsManagement
{
    /// <summary>
    /// Testen ob der Aktuelle user auch das Recht besitzt, sich den entsprechenden Inhalt anzeigen zu lassen.
    /// </summary>
    public class WebRights
    {
        #region Static
        private static string m_httpRightContextName = "RightsHttpContextName";
        /// <summary>
        /// Gibt eine Instanz des WebUserRights zurück
        /// </summary>
        public static WebRights Rights()
        {
            //Den aktuellen dataContext nur für den aktuellen Request speichern
            if (HttpContext.Current.Items[m_httpRightContextName] == null)
            {
                IRightQueries rightQueries = new RightQueries(CurrentHttpContext.GetDataModel());
                WebRights webRights = new WebRights(rightQueries);
                HttpContext.Current.Items.Add(m_httpRightContextName, webRights);
            }
            return (WebRights)HttpContext.Current.Items[m_httpRightContextName];
        }

        /// <summary>
        /// Prüfen ob der User das passende Recht hat.
        /// </summary>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool HasRight(EMemberRight right)
        {
            return Rights().Check(right);
        }
        #endregion

        #region Properties
        /// <summary>
        /// Die aktuelle UserId
        /// </summary>
        private long CurrentUserId { get; set; }

        /// <summary>
        /// Die aktuellen WebQueries
        /// </summary>
        private IRightQueries RightQueries { get; set; }
        #endregion

        #region Konstruktor
        /// <summary>
        /// Private Konstruktor für die WebUserRights, welche nur über die Statische Funktion initialisiert werden kann.
        /// </summary>
        public WebRights(IRightQueries rightQueries)
        {
            long userId;
            //Prüfen ob der User eingeloggt ist und die UserId des aktuell eingeloggten Benuzers ermitteln
            if (HttpContext.Current.User.Identity.IsAuthenticated && long.TryParse(HttpContext.Current.User.Identity.Name, out userId))
            {
                CurrentUserId = userId;
            }

            if (rightQueries == null)
            {
                throw new NullReferenceException("Rightqueries is Null");
            }

            RightQueries = rightQueries;
        }
        #endregion

        #region public functions
        /// <summary>
        /// Prüft ob der aktuelle User das Recht hat was übergeben wird.
        /// Das Überprüfen der Rechte muss beim Erstellen der Links durchgeführt werden sowie im CustomAuthorizeAttribute für 
        /// das Prüfen der jeweiligen Controllerrechte, das diese Aktionen dann auch nicht ausgeführt werden können.
        /// </summary>
        /// <param name="userRight">Das Recht was überprüft werden soll</param>
        /// <returns>TRUE->Aktueller Benutzer hat das Recht | FALSE->Aktuelle benutzer hat das Recht NICHT</returns>
        public virtual bool Check(EMemberRight userRight)
        {
            //Prüfen ob der aktuelle User eingeloggt ist.
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                //Wenn es sich um einen Admin handelt, dieser darf alles.
                if (IsAdmin())
                {
                    return true;
                }

                //Das Recht Prüfen und zurück gegeben oder der User das Recht hat oder nicht.
                if (RightQueries.HasRight(CurrentUserId, userRight))
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Prüfen ob es sich um einen Administrator handelt der eingeloggt ist.
        /// </summary>
        /// <returns>TRUE->IsAdmin | FALSE->Kein Admin</returns>
        public virtual bool IsAdmin()
        {
            //Prüfen ob der aktuelle User eingeloggt ist und Admin ist.
            if (HttpContext.Current.User.Identity.IsAuthenticated && RightQueries.IsAdmin(CurrentUserId))
            {
                return true;
            }

            return false;
        }
        #endregion
    }
}